#include "libSI.h"

#include <xstatus.h>
#include <xbasic_types.h>

//****************************************************************
#define NUM_WORDS_FRAME			41
#define NUM_BITS_WORD			32
#define NUM_PALABRAS_ENTRADA_TB	4
//****************************************************************
int partial(int blockFDRI, unsigned int major, unsigned int minor, int nWord, int num_word, int nBit);
int generate_max_major(int major_address, int minor_address, int block_FDRI);
int generate_max_minor(int major_address, int num_word, int block_FDRI);
int scan();
void ejecutar();
void ejecutar_reset();
void enviarErrores();
void reconfiguracion();

//VARIABLES
volatile unsigned int *dato, *respuesta;
volatile unsigned int error[NUM_PALABRAS_ENTRADA_TB], dato_salida[NUM_PALABRAS_ENTRADA_TB], dato_golden[NUM_PALABRAS_ENTRADA_TB];
volatile unsigned int comando, num_entradas_tb, recibidos, enviados;
volatile unsigned int ciclo_error = 0;
volatile unsigned int i, j, k, m, u = 0, desp;
volatile unsigned int num_FDRI_block, num_FDRI_block_address, major, major_address, max_major, minor, minor_address, max_minor, word, word_address, num_word, bit, bit_address = 0;
volatile unsigned int reconfiguracion_correcta, bit_parcial_correcto = 0;
volatile unsigned int tam_bit, tam_bit_modificado, tam_bit_restorer = 0;
volatile unsigned int dato_syn = 204;
volatile unsigned int status = 0;

//Variable global que indica cuantas transacciones seguidas
// se pueden hacer hasta que se sincronize FPGA y PC
static int syncSerie = 10;
static int unsigned invalid_HCLK_word = 0x10101010;
static int unsigned invalid_IOB_word = 0x20202020;
static int unsigned invalid_BRAM_word = 0x30303030;
static int unsigned invalid_CLK_word = 0x40404040;

static const int minor_per_column[65] = {54,36,36,36,36,30,36,36,36,36,36,36,36,36,36,36,30,36,36,28,36,36,36,36,36,36,36,36,54,4,
											36,36,36,36,36,36,36,36,36,36,36,36,30,36,36,36,36,36,36,36,36,36,36,30,36,36,36,36,54,36,36,36,36,30,32};

XHwIcap icap;

int main (void) {
	inicializarUart();
	status = inicializarIcap(&icap);
	
	while(1){
		recibirDato(&comando);

		switch(comando){
			//Recibir testbench
			case 0 :
				//Se le envía la infromación sobre el número de entradas del testbench
				// y el número de palabras de cada entrada antes de poder
				// inicialiar la UART
				recibirDato(&num_entradas_tb);
				recibirDato(dato);
				inicializarAdaptadorCircuito(*dato);

				for (recibidos=0;recibidos<num_entradas_tb;recibidos++){
					desp = recibidos*getPalabrasPorEntradaTB();
					if((recibidos % syncSerie) == 0)enviarDato(&dato_syn);
					recibirEntradaTB(pto_ram_testbench + desp);
				}
				break;

			//Generar Golden
			case 1 :
				for(i=0;i<num_entradas_tb;i++){
					desp = i*getPalabrasPorEntradaTB();
					escribirEntradaTB(pto_ram_testbench+desp);
					leerEntradaTB(pto_ram_golden+desp);
				}
				enviarDato(&dato_syn);
				break;

			//Ejecutar testbench
			case 2 :
				ejecutar();
				enviarDato(&dato_syn);
				enviarErrores();
				break;

			//Enviar golden
			case 3 :
				for (enviados=0;enviados<num_entradas_tb;enviados++){
					desp = enviados*getPalabrasPorEntradaTB();
					if((enviados % syncSerie) == 0)enviarDato(&dato_syn);
					enviarEntradaTB(pto_ram_golden+desp);
				}
				break;
			//Cargar golden
			case 4 :
				for (recibidos=0;recibidos<num_entradas_tb;recibidos++){
					desp = recibidos*getPalabrasPorEntradaTB();
					if((recibidos % syncSerie) == 0)enviarDato(&dato_syn);
					recibirEntradaTB(pto_ram_golden + desp);
				}
				break;
			//Reconfiguración
			case 5 :
				recibirDato(&tam_bit);
				enviarDato(&status);
				if(status == XST_SUCCESS){
					//Scaneamos el bitstream parcial original, para saber el tamaño y numero de divisiones
					//que ha hecho el planahead en el bitstream parcial
					status = scan();

					enviarDato(&dato_syn);
					enviarDato(pto_ram_FDRI_blocks);
					recibirDato(&num_FDRI_block_address);
					//num_FDRI_block_address = 1;
					//Para cada bloque, hacemos un barrido inyectando errores
					for (num_FDRI_block = num_FDRI_block_address ; num_FDRI_block <= *pto_ram_FDRI_blocks ; num_FDRI_block ++){
						num_word = 0;

						major_address = *(pto_ram_FDRI_blocks + ((3 * (num_FDRI_block - 1)) + 2));
						minor_address = *(pto_ram_FDRI_blocks + ((3 * (num_FDRI_block - 1)) + 3));
						max_major = generate_max_major(major_address,minor_address,num_FDRI_block);
						enviarDato(&dato_syn);
						enviarDato(pto_ram_FDRI_blocks + ((3 * (num_FDRI_block - 1)) + 1));
						enviarDato(&major_address);
						enviarDato(&minor_address);
						//Recibir datos
						enviarDato(&dato_syn);
						recibirDato(&num_word);
						recibirDato(&major_address);
						recibirDato(&minor_address);
						recibirDato(&word_address);
						recibirDato(&bit_address);

						for (major = major_address ; major < max_major ; major ++){
							max_minor = generate_max_minor(major, num_word, num_FDRI_block);
							for (minor = minor_address ; minor < max_minor ; minor ++){
								minor_address = 0;
								for (word = word_address ; word <= NUM_WORDS_FRAME ; word ++){
									word_address = 1;
									num_word ++;
									for (bit = bit_address ; bit < NUM_BITS_WORD ; bit ++){
										bit_address = 0;
										if (minor_per_column[major] == 54)
											{
											enviarDato(&dato_syn);
											enviarDato(&invalid_IOB_word);
											bit = NUM_BITS_WORD;
											}
										else if (minor_per_column[major] == 30)
											{
											enviarDato(&dato_syn);
											enviarDato(&invalid_BRAM_word);
											bit = NUM_BITS_WORD;
											}
										else if (minor_per_column[major] == 4)
											{
											enviarDato(&dato_syn);
											enviarDato(&invalid_CLK_word);
											bit = NUM_BITS_WORD;
											}
										else if (word == 21)
											{
											enviarDato(&dato_syn);
											enviarDato(&invalid_HCLK_word);
											bit = NUM_BITS_WORD;
											}
										else
											{
											//Generamos el bitstream parcial con un bitflip
											//Parámetros:
											// j = número de palabra
											// k = número de bits por palabra
											// i = número de bloque
											partial(num_FDRI_block,major,minor,word,num_word,bit);
											status = programar_icap(&icap,(Xuint32 *)pto_ram_bitModificado,(Xuint32)tam_bit_modificado);
											ejecutar();
											enviarDato(&dato_syn);
											enviarErrores();

											//status = programar_icap(&icap,(Xuint32 *)pto_ram_bitRestorer,(Xuint32)tam_bit_restorer);
											//status = programar_icap(&icap,(Xuint32 *)pto_ram_bitOriginal,(Xuint32)tam_bit);
											//ejecutar();
											//ejecutar_reset();
											//ciclo_error = 0;
											//enviarDato(&dato_syn);
											//enviarErrores();
											}
									}
								}
							}
						}

					}
				}
				status = XST_SUCCESS;

				break;

			//Comprobar sincronización
			case 6 :
				*respuesta=0xf0f0f0f0;
				enviarDato(respuesta);
				break;

			//Recibir el bitstream parcial
			case 7 :
				recibirDato(&tam_bit);
				recibidos = 0;
				while (recibidos < tam_bit) {
					recibirDato(pto_ram_bitOriginal + recibidos);
					recibidos = recibidos + 1;
				}
				break;
			//Enviar testbench
			case 8 :
				for(enviados=0;enviados<num_entradas_tb;enviados++){
					desp = enviados*getPalabrasPorEntradaTB();
					if((enviados % syncSerie) == 0) enviarDato(&dato_syn);
					enviarEntradaTB(pto_ram_testbench+desp);
				}
				break;
			default:
				break;
		}
	}
   return 0;
}

void ejecutar(){
	ciclo_error = 0;
	for(i=0;i<getPalabrasPorEntradaTB();i++){
		error[i] = 0;
		dato_salida[i] = 0;
		dato_golden[i] = 0;
	}
	m=0;
	while(m<num_entradas_tb && !existeError()){
		desp = m*getPalabrasPorEntradaTB();
		for(i=0;i<getPalabrasPorEntradaTB();i++){
			dato_golden[i] = *(pto_ram_golden+desp+i);
		}
		escribirEntradaTB(pto_ram_testbench+desp);
		leerEntradaTB(dato_salida);
		for(i=0;i<getPalabrasPorEntradaTB();i++){
			error[i] = dato_salida[i] ^ dato_golden[i];
		}

		m=m+1;
		if(existeError()){
			ciclo_error = m;
			return;
		}
	}
}

//Devuelve >0 si existe error, 0 en caso contrario
int existeError(){
	int ret=0;
	for(i=0;i<getPalabrasPorEntradaTB();i++){
		if(error[i] != 0) ret=ret+1;
	}
	return ret;
}

void ejecutar_reset(){
		*(pto_circuito_entrada) = 0x80000000;
		*(pto_circuito_entrada) = 0x80000000;
}


void enviarErrores(){
	enviarDato(&ciclo_error);
	if (ciclo_error != 0){
		status = programar_icap(&icap,(Xuint32 *)pto_ram_bitOriginal,(Xuint32)tam_bit);
		//ejecutar_reset();
	}else if ((word == NUM_WORDS_FRAME) && (bit == (NUM_BITS_WORD - 1))){
		status = programar_icap(&icap,(Xuint32 *)pto_ram_bitRestorer,(Xuint32)tam_bit_restorer);
		//ejecutar_reset();
	}
}




//******************* CÓDIGO DE LA RECONFIGURACIÓN PARCIAL **********************
#define DUMMY_WORD				0xFFFFFFFF
#define BUS_WIDTH_WORD			0x000000BB
#define BUS_WIDTH_DETECT_WORD	0x11220044
#define SYNC_WORD 				0xAA995566
#define NOOP 					0x20000000
#define PACKET_MASK  			0x60000000
#define TYPE_1_WORD 			0x20000000
#define TYPE_2_WORD 			0x40000000
#define OPCODE_MASK		 		0x18000000
#define TYPE_READ 				0x08000000
#define TYPE_WRITE 				0x10000000
#define WORD_COUNT_1 			0x000007FF
#define WORD_COUNT_2 			0x07FFFFFF
#define REG_MASK 				0x0003E000
#define CRC 					0x00000000
#define FAR 					0x00002000
#define BLOCK_TYPE_MASK			0x00E00000
#define TOP_BOTTON_MASK			0x00100000
#define ROW_MASK				0x000F8000
#define MAJOR_MASK				0x00007F80
#define MINOR_MASK				0x0000007F
#define FDRI 					0x00004000
#define FDRO 					0x00006000
#define CMD 					0x00008000
#define CTL0 					0x0000A000
#define MASK 					0x0000C000
#define STAT 					0x0000E000
#define LOUT 					0x00010000
#define COR0 					0x00012000
#define MFWR 					0x00014000
#define IDCODE 					0x00018000
#define AXSS 					0x0001A000
#define COR1 					0x0001C000
#define CSOB					0x0001E000
#define WBSTAR					0x00020000
#define TIMER					0x00022000
#define CBC						0x00026000
#define BOOTSTS					0x0002C000
#define CTL1					0x00030000

#define FULL_MASK				0xFFFFFFFF

#define INST_NO_CRC 			0x0000DEFC
#define INST_CRC_DISABLED		0x10000000

int generate_max_major(int major_address, int minor_address, int block_FDRI)
	{
	int num_words = *(pto_ram_FDRI_blocks + ((3 * (block_FDRI - 1)) + 1));
	int num_frames = (num_words - NUM_WORDS_FRAME) / NUM_WORDS_FRAME;
	int max_major_address = major_address;
	if (minor_address != 0)
		{
		num_frames = num_frames - (minor_per_column[major_address] - minor_address);
		max_major_address ++;
		}
	while (num_frames > 0)
		{
		num_frames = num_frames - minor_per_column[major_address];
		max_major_address ++;
		}
	return max_major_address;
	}
	
int generate_max_minor(int major_address, int num_word, int block_FDRI)
	{
	int num_words = *(pto_ram_FDRI_blocks + ((3 * (block_FDRI - 1)) + 1));
	num_words = num_words - num_word;
	int num_frames = (num_words - NUM_WORDS_FRAME) / NUM_WORDS_FRAME;
	int max_minor_address = minor_per_column[major_address];
	if (num_frames < minor_per_column[major_address])
		max_minor_address = num_frames;
	return max_minor_address;
	}
	
int scan()
	{
	volatile int index = 0;
	volatile unsigned int instruccion;
	volatile int numWords;
	volatile int sync = 0;
	volatile int num_FDRI_blocks = 0;
	volatile unsigned int major;
	volatile unsigned int minor;

	while (!sync)
		{
		instruccion = *(pto_ram_bitOriginal + index);
		if (instruccion != SYNC_WORD)
			index ++;
		else
			sync = 1;
		if (index == tam_bit)
			return -2;
		}

	while (index < tam_bit)
		{
		instruccion = *(pto_ram_bitOriginal + index);
		if (instruccion == SYNC_WORD)
			{
			}
		else if (instruccion == NOOP)
			{
			}
		else if ((instruccion & PACKET_MASK) == TYPE_1_WORD)
			{
			if ((instruccion & OPCODE_MASK) == TYPE_WRITE)
				{
				switch (instruccion & REG_MASK)
					{
					case CRC :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case FAR :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							major = (instruccion & MAJOR_MASK) >> 7;
							minor = instruccion & MINOR_MASK;
							*(pto_ram_FDRI_blocks + ((num_FDRI_blocks * 3) + 2)) = major;
							*(pto_ram_FDRI_blocks + ((num_FDRI_blocks * 3) + 3)) = minor;
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case FDRI :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						*(pto_ram_FDRI_blocks + ((num_FDRI_blocks * 3) + 1)) = numWords;
						num_FDRI_blocks ++;
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case FDRO :
						break;
					case CMD :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case CTL0 :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case MASK :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case STAT :
						break;
					case LOUT :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case COR0 :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case MFWR :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case IDCODE :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case AXSS :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case COR1 :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case CSOB :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case WBSTAR :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case TIMER :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case CBC :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case BOOTSTS :
						break;
					case CTL1 :
						numWords = instruccion & WORD_COUNT_1;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					}
				}
			else if ((instruccion & OPCODE_MASK) == TYPE_READ)
				{
				numWords = instruccion & WORD_COUNT_1;
				index ++;
				if (index == tam_bit)
					return -1;
				instruccion = *(pto_ram_bitOriginal + index);
				if (numWords == 0)
					{
					if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
						{
						index --;
						break;
						}
					else
						{
						numWords = instruccion & WORD_COUNT_2;
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						}
					}
				for (u = 1 ; u <= numWords ; u++)
					{
					index ++;
					if (index == tam_bit)
						return -1;
					instruccion = *(pto_ram_bitOriginal + index);
					}
				index --;
				}
			}
		index ++;
		}
	*pto_ram_FDRI_blocks = num_FDRI_blocks;
	return 1;
	}


int partial(int blockFDRI, unsigned int major, unsigned int minor, int nWord, int num_word, int nBit)
	{

	volatile unsigned int sync = 0;
	volatile unsigned int index = 0;
	volatile unsigned int index_aux = 0;
	volatile unsigned int index_mod = 0;
	volatile unsigned int index_rest = 0;
	volatile unsigned int instruccion;
	volatile unsigned int numWords;
	volatile unsigned int num_FDRI_blocks = 0;

	while ((!sync) && (index != tam_bit))
		{
		instruccion = *(pto_ram_bitOriginal + index);
		if (instruccion != SYNC_WORD)
			{
			if ((instruccion == DUMMY_WORD) || (instruccion == BUS_WIDTH_WORD) || (instruccion == BUS_WIDTH_DETECT_WORD))
				{
				*(pto_ram_bitModificado + index_mod) = instruccion;
				*(pto_ram_bitRestorer + index_rest) = instruccion;
				index_mod ++;
				index_rest ++;
				}
			index ++;
			}
		else
			sync = 1;
		}

	while (index < tam_bit)
		{
		instruccion = *(pto_ram_bitOriginal + index);
		if (instruccion == SYNC_WORD)
			{
			*(pto_ram_bitModificado + index_mod) = instruccion;
			*(pto_ram_bitRestorer + index_rest) = instruccion;
			index_mod ++;
			index_rest ++;
			}
		else if (instruccion == NOOP)
			{
			*(pto_ram_bitModificado + index_mod) = instruccion;
			*(pto_ram_bitRestorer + index_rest) = instruccion;
			index_mod ++;
			index_rest ++;
			}
		else if ((instruccion & PACKET_MASK) == TYPE_1_WORD)
			{
			if ((instruccion & OPCODE_MASK) == TYPE_WRITE)
				{
				switch (instruccion & REG_MASK)
					{
					case CRC :
						numWords = instruccion & WORD_COUNT_1;
						//*(pto_ram_bitModificado + index_mod) = instruccion;
						//*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						//index_mod ++;
						//index_rest++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								//*(pto_ram_bitModificado + index_mod) = instruccion;
								//*(pto_ram_bitRestorer + index_rest) = instruccion;
								index ++;
								//index_mod ++;
								//index_rest ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							instruccion = INST_NO_CRC;
							//*(pto_ram_bitModificado + index_mod) = instruccion;
							//*(pto_ram_bitRestorer + index_rest) = instruccion;
							index ++;
							//index_mod ++;
							//index_rest ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case FAR :
						numWords = instruccion & WORD_COUNT_1;
						if (((num_FDRI_blocks + 1) == blockFDRI) || (num_FDRI_blocks == *pto_ram_FDRI_blocks))
							{
							*(pto_ram_bitModificado + index_mod) = instruccion;
							*(pto_ram_bitRestorer + index_rest) = instruccion;
							index_mod ++;
							index_rest++;
							}
						index ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								if (((num_FDRI_blocks + 1) == blockFDRI) || (num_FDRI_blocks == *pto_ram_FDRI_blocks))
									{
									*(pto_ram_bitModificado + index_mod) = instruccion;
									*(pto_ram_bitRestorer + index_rest) = instruccion;
									index_mod ++;
									index_rest++;
									}
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							if (((num_FDRI_blocks + 1) == blockFDRI) || (num_FDRI_blocks == *pto_ram_FDRI_blocks))
								{
								instruccion = (instruccion & (~ MAJOR_MASK)) | (major << 7);
								instruccion = (instruccion & (~ MINOR_MASK)) | minor;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								index_mod ++;
								index_rest++;
								}
							index ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case FDRI :
						numWords = instruccion & WORD_COUNT_1;
						if ((num_FDRI_blocks + 1) == blockFDRI)
							{
							*(pto_ram_bitModificado + index_mod) = (instruccion & (~ WORD_COUNT_1)) | (NUM_WORDS_FRAME * 2);
							*(pto_ram_bitRestorer + index_rest) = (instruccion & (~ WORD_COUNT_1)) | (NUM_WORDS_FRAME * 2);
							index_mod ++;
							index_rest ++;
							}
						index ++;
						num_FDRI_blocks ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								//if (num_FDRI_blocks == blockFDRI)
								//	{
								//	*(pto_ram_bitModificado + index_mod) = instruccion;
								//	*(pto_ram_bitRestorer + index_rest) = instruccion;
								//	index_mod ++;
								//	index_rest ++;
								// }
								index ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						if (num_FDRI_blocks != blockFDRI)
							{
							index = index + numWords;
							numWords = 0;
							}
						else
							{
							num_word = ((num_word - 1) / NUM_WORDS_FRAME) * NUM_WORDS_FRAME;
							index_aux = index;
							index = index + num_word;
							for (u = 1 ; u <= 2 * NUM_WORDS_FRAME; u++)
								{
								instruccion = *(pto_ram_bitOriginal + index);
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								if(nWord == u)
									//instruccion = instruccion ^ (0xFFFFFFFF);
									instruccion = instruccion ^ (0x00000001 << nBit);
								*(pto_ram_bitModificado + index_mod) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							/*
							index = (index - NUM_WORDS_FRAME - num_word) + (numWords - NUM_WORDS_FRAME);
							for (u = 1 ; u <= NUM_WORDS_FRAME; u++)
								{
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							*/
							index = ((index - num_word) - (2 * NUM_WORDS_FRAME)) + numWords;
							index = index_aux + numWords;
							}
						index --;
						break;
					case FDRO :
						break;
					case CMD :
						numWords = instruccion & WORD_COUNT_1;
						*(pto_ram_bitModificado + index_mod) = instruccion;
						*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						index_mod ++;
						index_rest++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							*(pto_ram_bitModificado + index_mod) = instruccion;
							*(pto_ram_bitRestorer + index_rest) = instruccion;
							index ++;
							index_mod ++;
							index_rest ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case CTL0 :
						numWords = instruccion & WORD_COUNT_1;
						*(pto_ram_bitModificado + index_mod) = instruccion;
						*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						index_mod ++;
						index_rest++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							*(pto_ram_bitModificado + index_mod) = instruccion;
							*(pto_ram_bitRestorer + index_rest) = instruccion;
							index ++;
							index_mod ++;
							index_rest ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case MASK :
						numWords = instruccion & WORD_COUNT_1;
						*(pto_ram_bitModificado + index_mod) = instruccion;
						*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						index_mod ++;
						index_rest++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							*(pto_ram_bitModificado + index_mod) = instruccion;
							*(pto_ram_bitRestorer + index_rest) = instruccion;
							index ++;
							index_mod ++;
							index_rest ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case STAT :
						break;
					case LOUT :
						numWords = instruccion & WORD_COUNT_1;
						*(pto_ram_bitModificado + index_mod) = instruccion;
						*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						index_mod ++;
						index_rest++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							*(pto_ram_bitModificado + index_mod) = instruccion;
							*(pto_ram_bitRestorer + index_rest) = instruccion;
							index ++;
							index_mod ++;
							index_rest ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case COR0 :
						numWords = instruccion & WORD_COUNT_1;
						*(pto_ram_bitModificado + index_mod) = instruccion;
						*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						index_mod ++;
						index_rest++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							*(pto_ram_bitModificado + index_mod) = instruccion | INST_CRC_DISABLED;
							*(pto_ram_bitRestorer + index_rest) = instruccion | INST_CRC_DISABLED;
							index ++;
							index_mod ++;
							index_rest ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case MFWR :
						numWords = instruccion & WORD_COUNT_1;
						*(pto_ram_bitModificado + index_mod) = instruccion;
						*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						index_mod ++;
						index_rest++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							*(pto_ram_bitModificado + index_mod) = instruccion;
							*(pto_ram_bitRestorer + index_rest) = instruccion;
							index ++;
							index_mod ++;
							index_rest ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case IDCODE :
						numWords = instruccion & WORD_COUNT_1;
						*(pto_ram_bitModificado + index_mod) = instruccion;
						*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						index_mod ++;
						index_rest ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							*(pto_ram_bitModificado + index_mod) = instruccion;
							*(pto_ram_bitRestorer + index_rest) = instruccion;
							index ++;
							index_mod ++;
							index_rest ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case AXSS :
						numWords = instruccion & WORD_COUNT_1;
						*(pto_ram_bitModificado + index_mod) = instruccion;
						*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						index_mod ++;
						index_rest++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							*(pto_ram_bitModificado + index_mod) = instruccion;
							*(pto_ram_bitRestorer + index_rest) = instruccion;
							index ++;
							index_mod ++;
							index_rest ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case COR1 :
						numWords = instruccion & WORD_COUNT_1;
						*(pto_ram_bitModificado + index_mod) = instruccion;
						*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						index_mod ++;
						index_rest++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							*(pto_ram_bitModificado + index_mod) = instruccion;
							*(pto_ram_bitRestorer + index_rest) = instruccion;
							index ++;
							index_mod ++;
							index_rest ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case CSOB :
						numWords = instruccion & WORD_COUNT_1;
						*(pto_ram_bitModificado + index_mod) = instruccion;
						*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						index_mod ++;
						index_rest++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							*(pto_ram_bitModificado + index_mod) = instruccion;
							*(pto_ram_bitRestorer + index_rest) = instruccion;
							index ++;
							index_mod ++;
							index_rest ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case WBSTAR :
						numWords = instruccion & WORD_COUNT_1;
						*(pto_ram_bitModificado + index_mod) = instruccion;
						*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						index_mod ++;
						index_rest++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							*(pto_ram_bitModificado + index_mod) = instruccion;
							*(pto_ram_bitRestorer + index_rest) = instruccion;
							index ++;
							index_mod ++;
							index_rest ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case TIMER :
						numWords = instruccion & WORD_COUNT_1;
						*(pto_ram_bitModificado + index_mod) = instruccion;
						*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						index_mod ++;
						index_rest++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							*(pto_ram_bitModificado + index_mod) = instruccion;
							*(pto_ram_bitRestorer + index_rest) = instruccion;
							index ++;
							index_mod ++;
							index_rest ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case CBC :
						numWords = instruccion & WORD_COUNT_1;
						*(pto_ram_bitModificado + index_mod) = instruccion;
						*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						index_mod ++;
						index_rest++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							*(pto_ram_bitModificado + index_mod) = instruccion;
							*(pto_ram_bitRestorer + index_rest) = instruccion;
							index ++;
							index_mod ++;
							index_rest ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					case BOOTSTS :
						break;
					case CTL1 :
						numWords = instruccion & WORD_COUNT_1;
						*(pto_ram_bitModificado + index_mod) = instruccion;
						*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						index_mod ++;
						index_rest++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						if (numWords == 0)
							{
							if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
								{
								index --;
								break;
								}
							else
								{
								numWords = instruccion & WORD_COUNT_2;
								*(pto_ram_bitModificado + index_mod) = instruccion;
								*(pto_ram_bitRestorer + index_rest) = instruccion;
								index ++;
								index_mod ++;
								index_rest ++;
								if (index == tam_bit)
									return -1;
								instruccion = *(pto_ram_bitOriginal + index);
								}
							}
						for (u = 1 ; u <= numWords ; u++)
							{
							*(pto_ram_bitModificado + index_mod) = instruccion;
							*(pto_ram_bitRestorer + index_rest) = instruccion;
							index ++;
							index_mod ++;
							index_rest ++;
							if (index == tam_bit)
								return -1;
							instruccion = *(pto_ram_bitOriginal + index);
							}
						index --;
						break;
					}
				}
			else if ((instruccion & OPCODE_MASK) == TYPE_READ)
				{
				numWords = instruccion & WORD_COUNT_1;
				*(pto_ram_bitModificado + index_mod) = instruccion;
				*(pto_ram_bitRestorer + index_rest) = instruccion;
				index ++;
				index_mod ++;
				index_rest++;
				if (index == tam_bit)
					return -1;
				instruccion = *(pto_ram_bitOriginal + index);
				if (numWords == 0)
					{
					if ((instruccion & PACKET_MASK) != TYPE_2_WORD)
						{
						index --;
						break;
						}
					else
						{
						numWords = instruccion & WORD_COUNT_2;
						*(pto_ram_bitModificado + index_mod) = instruccion;
						*(pto_ram_bitRestorer + index_rest) = instruccion;
						index ++;
						index_mod ++;
						index_rest ++;
						if (index == tam_bit)
							return -1;
						instruccion = *(pto_ram_bitOriginal + index);
						}
					}
				for (u = 1 ; u <= numWords ; u++)
					{
					*(pto_ram_bitModificado + index_mod) = instruccion;
					*(pto_ram_bitRestorer + index_rest) = instruccion;
					index ++;
					index_mod ++;
					index_rest ++;
					if (index == tam_bit)
						return -1;
					instruccion = *(pto_ram_bitOriginal + index);
					}
				index --;
				}
			}
		index ++;
		}
	tam_bit_modificado = index_mod;
	tam_bit_restorer = index_rest;
	return 1;
	}



